//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include <Core/Core.hpp>
#include "Item.hpp"
#include "JSON.hpp"
#include "JSONHelpers.hpp"


namespace Config
{
	//////////////////////////////////////////////////////////////////////////
	// Provide type specific serialization.
	template< typename Type >
	class Serializer : public Item
	{
	public:
		//
		Serializer( const std::string& key )
		:	Config::Item( key )
		{}

	protected:
		//
		bool				_Load( Type& v, const JSONValue& inv )
		{
			if( inv.IsNumber() )
			{
				v = (Type)inv.AsNumber();
				return true;
			}
			return false;
		}

		JSONValue*			_Save( const Type& v ) const
		{
			return new JSONValue( (double)v );
		}
	};


	//
	template<>
	struct Serializer< bool > : public Config::Item
	{
		//
		Serializer( const std::string& key )
		:	Config::Item( key )
		{}

	protected:
		//
		bool				_Load( bool& v, const JSONValue& inv )
		{
			if( inv.IsBool() )
			{
				v = (bool)inv.AsBool();
				return true;
			}
			return false;
		}
		JSONValue*			_Save( const bool& v ) const
		{
			return new JSONValue( v );
		}
	};


	//
	template<>
	struct Serializer< std::string > : public Config::Item
	{
		//
		Serializer( const std::string& key )
		:	Config::Item( key )
		{}

	protected:
		//
		bool				_Load( std::string& v, const JSONValue& inv )
		{
			if( inv.IsString() )
			{
				v = string_cast< std::string >( inv.AsString() );
				return true;
			}
			return false;
		}
		JSONValue*			_Save( const std::string& v ) const
		{
			return new JSONValue( string_cast< std::wstring >( v ) );
		}
	};
}
